package com.ruijie.acl.web;

import java.util.ArrayList;
import java.util.List;

import javax.faces.model.SelectItem;

import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.Transactional;
import org.jboss.seam.international.StatusMessage.Severity;
import org.jboss.seam.jsf.ListDataModel;

import com.ruijie.acl.AccessGroup;
import com.ruijie.acl.Ace;
import com.ruijie.acl.Template;
import com.ruijie.acl.TimeRange;
import com.ruijie.acl.service.AccessGroupService;
import com.ruijie.acl.service.AceService;
import com.ruijie.acl.service.DeviceAccessGroupService;
import com.ruijie.acl.type.MoveDirection;
import com.ruijie.acl.type.PortTypeEnum;
import com.ruijie.acl.type.ProtocolTypeEnum;
import com.ruijie.foundation.bo.EntityObject;
import com.ruijie.foundation.exception.BusinessException;
import com.ruijie.foundation.security.internal.Authority;
import com.ruijie.foundation.service.Repository;
import com.ruijie.foundation.web.intercept.AddSuccessInfo;
import com.ruijie.acl.utils.AclUtil;

@Name("aceAction")
@Scope(ScopeType.CONVERSATION)
@AddSuccessInfo
public class AceAction extends AclBaseAction {
	@In("#{aceService}")
	private AceService aceService;
	@In("#{accessGroupService}")
	private AccessGroupService accessGroupService;
	@In("#{deviceAccessGroupService}")
	private DeviceAccessGroupService deviceAccessGroupService;
	@In("#{accessGroupAction}")
	private AccessGroupAction accessGroupAction;
	@In("#{deviceManageInAccessGroupAction}")
	private DeviceManageInAccessGroupAction deviceManageInAccessGroupAction;
	private Ace model;
	private Ace criteria = new Ace();
	private boolean allowPaged = true;
	private boolean showParticular = false;
	private ListDataModel entityModelList = null;
	private EntityObject paramObject = null;
	private String paramType = "";
	private String aceOrder = "";
	private Integer aceCount = 0;
	private String timeRangeName = null;
	private String sourcePort = "";
	private String desPort = "";
	
	private boolean timeRangeChangedFlag = false;

	public String getSourcePort() {
		return sourcePort;
	}

	public void setSourcePort(String sourcePort) {
		this.sourcePort = sourcePort;
	}

	public String getDesPort() {
		return desPort;
	}

	public void setDesPort(String desPort) {
		this.desPort = desPort;
	}

	public String getTimeRangeName() {
		return timeRangeName;
	}

	public void setTimeRangeName(String timeRangeName) {
		this.timeRangeName = timeRangeName;
	}

	public String getAceOrder() {
		return aceOrder;
	}

	public void setAceOrder(String aceOrder) {
		this.aceOrder = aceOrder;
	}

	public String getParamType() {
		return paramType;
	}

	public void setParamType(String paramType) {
		this.paramType = paramType;
	}

	@SuppressWarnings("unchecked")
	@Override
	protected Repository getRepository() {
		return aceService;
	}

	@Override
	protected String getAddPage() {
		if (this.paramType == "Template") {
			return "/acl/aclTemplate/aceAdd4Template.seam";
		}
		return "/acl/aceAdd.seam";
	}

	@Override
	public EntityObject getCriteria() {
		return this.criteria;
	}

	@Override
	protected String getDetailPage() {
		if (this.paramType == "Template") {
			return "/acl/aclTemplate/aceDetail4Template.seam";
		}
		return "/acl/aceDetail.seam";
	}
	
	public String toTempageDetailPage(EntityObject model,String previousPage){
		this.setPreviousPage(previousPage);
		setModel(refreshModel(model));
		return "/acl/aclTemplate/aceDetail4Template.seam";
	}
	
	@Override
	public void delete() {
		if (null == getIds() || getIds().length == 0)
            return;
        try {
        	Long[] ids = getIds();
        	AccessGroup tempAg = aceService.get(ids[0]).getAccessGroup();
        	this.updateAccessGroupChangeFlag(tempAg);
            if (!doDelete()) {
                return;
            }
        } catch (BusinessException e) {
            // 清除多选框选定记录
            selectedIds.clear();
            throw e;
        }
        updateModel();
        // 如果当前页面已经没有记录(例如删除了当前页面的所有记录)，那么显示上一页
        if (currentPage.getTotalPageCount() < page && page > 1) {
            page--;
            updateModel();
        }
        
        // 清除多选框选定记录
        selectedIds.clear();
        addGlobalI18nMessage(getDelSuccessMsg());
	}

	

	@Override
	protected String getListPage() {
		return "/acl/aceDetail.seam";
	}

	@Override
	public EntityObject getModel() {
		if (model == null) {
			model = new Ace();
		}
		return model;
	}

	@Override
	protected String getUpdatePage() {
		if (this.paramType == "Template") {
			return "/acl/aclTemplate/aceEdit4Template.seam";
		}
		return "/acl/aceEdit.seam";
	}

	@Override
	protected String getToPageAfterAdd() {
		page = 1;
		this.updateModel();
		if (this.getPreviousPage() == null || this.getPreviousPage().equals("")) {
			return this.getListPage();
		} else {
			return this.getPreviousPage();
		}
	}

	@Override
	protected String getToPageAfterUpdate() {
		page = 1;
		this.updateModel();
		if (this.getPreviousPage() == null || this.getPreviousPage().equals("")) {
			return this.getListPage();
		} else {
			return this.getPreviousPage();
		}
	}

	@Override
	public void resetModel() {
		this.model = null;
		this.model = new Ace();
		this.aceOrder = "";
	}

	@Override
	public void setCriteria(EntityObject criteria) {
		this.criteria = (Ace) criteria;
	}

	@Override
	public void setModel(EntityObject model) {
		this.model = (Ace) model;
	}

	public boolean isAllowPaged() {
		return allowPaged;
	}

	public void setAllowPaged(boolean allowPaged) {
		if (this.allowPaged != allowPaged) {
			entityModelList = null;
			this.allowPaged = allowPaged;
		}
	}

	public boolean isShowParticular() {
		return showParticular;
	}

	public void setShowParticular(boolean showParticular) {
		this.showParticular = showParticular;
	}

	/**
	 * 取得列表数据
	 * 
	 * @param entity
	 *            模板
	 * @return 列表数据
	 */
	@SuppressWarnings("unchecked")
	public ListDataModel getEntityModelList(Template entity) {
		return getEntityModelList(entity, this.allowPaged);
	}

	/**
	 * 取得列表数据
	 * 
	 * @param entity
	 *            时间段
	 * 
	 * @return 列表数据
	 */
	@SuppressWarnings("unchecked")
	public ListDataModel getEntityModelList(TimeRange entity) {
		// if (entityModelList == null){
		this.paramObject = entity;
		this.paramType = "TimeRange";
		adjustPage();
		currentPage = this.aceService.pageQueryByTimeRange(entity, page, pageSize);
		entityModelList = new ListDataModel((List<Ace>) currentPage.getResult());
		// }
		return entityModelList;
	}

	/**
	 * 取得列表数据
	 * 
	 * @param entity
	 *            ACL组
	 * 
	 * @return 列表数据
	 */
	@SuppressWarnings("unchecked")
	public ListDataModel getEntityModelList(AccessGroup entity) {

		return getEntityModelList(entity, this.allowPaged);

	}

	/**
	 * 取得列表数据
	 * 
	 * @param entity
	 *            ACL组
	 * 
	 * @param flag
	 *            分页标识
	 * @return 列表数据
	 */
	@SuppressWarnings("unchecked")
	public ListDataModel getEntityModelList(AccessGroup entity, boolean flag) {
		// if (entityModelList == null){
		this.paramObject = entity;
		this.paramType = "AccessGroup";
		if (flag) {
			adjustPage();
			currentPage = this.aceService.pageQueryByAccessGroup(entity, page, pageSize);
			entityModelList = new ListDataModel((List<Ace>) currentPage.getResult());
			this.aceCount = this.getTotalCount();
		} else {
			List<Ace> aceList = this.aceService.getByAccessGroup(entity);
			entityModelList = new ListDataModel(aceList);
			this.aceCount = aceList.size();
		}
		// }
		return entityModelList;
	}

	/**
	 * 取得列表数据
	 * 
	 * @param entity
	 *            ACL组
	 * 
	 * @param flag
	 *            分页标识
	 * @return 列表数据
	 */
	@SuppressWarnings("unchecked")
	public ListDataModel getEntityModelList(Template entity, boolean flag) {
		// if (entityModelList == null){
		this.paramObject = entity;
		this.paramType = "Template";
		if (flag) {
			adjustPage();
			currentPage = this.aceService.pageQueryByTemplate(entity, page, pageSize);
			entityModelList = new ListDataModel((List<Ace>) currentPage.getResult());
			this.aceCount = this.getTotalCount();
		} else {
			List<Ace> aceList = this.aceService.getByTemplate(entity);
			entityModelList = new ListDataModel(aceList);
			this.aceCount = aceList.size();
		}

		// }
		return entityModelList;
	}

	public String toAddPage(AccessGroup entity, String lastPage) {
		this.sourcePort = null;
		this.desPort = null;
		this.timeRangeName = null;
		String result = super.toAddPage(lastPage);
		this.model.setAccessGroup(entity);
		return result;
	}

	public String toAddPage(Template entity, String lastPage) {
		this.sourcePort = null;
		this.desPort = null;
		this.timeRangeName = null;
		String result = super.toAddPage(lastPage);
		this.model.setTemplate(entity);
		return result;
	}

	@SuppressWarnings("unchecked")
	@Override
	protected void updateModel() {
		this.entityModelList = null;
		if (this.paramObject == null) {
			super.updateModel();
		} else if (this.paramObject instanceof AccessGroup) {
			this.getEntityModelList((AccessGroup) (this.paramObject));
		} else if (this.paramObject instanceof TimeRange) {
			this.getEntityModelList((TimeRange) (this.paramObject));
		} else if (this.paramObject instanceof Template) {
			this.getEntityModelList((Template) (this.paramObject));
		}
	}

	/**
	 * 移动规则顺序
	 * 
	 * @param entity
	 *            规则
	 * @param direction
	 *            方向枚举
	 */
	public void moveAceOrder(Ace entity, MoveDirection direction) {
		aceService.updateAceNumWithDirection(entity, direction);
		this.updateModel();
		this.updateAccessGroupChangeFlag(entity.getAccessGroup());
	}

	/**
	 * 移动规则顺序
	 * 
	 * @param entity
	 *            规则
	 * @param direction
	 *            方向
	 */
	public void moveAceOrder(Ace entity, String direction) {
		MoveDirection md = MoveDirection.valueOf(direction);
		this.moveAceOrder(entity, md);
	}

	@Override
	@SuppressWarnings("unchecked")
	@Transactional
	protected boolean doAdd() {
		/*-----------modify by sinyee 2010-11-4--------------------*/
		if(model!=null){
		this.model.setId(null);
		
		// 处理源端口和目的端口
		if (AclUtil.empty(this.model.getSourcePort())) {
			this.model.setSourcePort(this.sourcePort);
		}
		if (AclUtil.empty(this.model.getDesPort())) {
			this.model.setDesPort(this.desPort);
		}
		if (this.paramObject instanceof Template) {
			AclUtil.filterAce(this.model, ((Template) paramObject).getAccessGroupType());
		} else if (this.paramObject instanceof AccessGroup) {
			AclUtil.filterAce(this.model, ((AccessGroup) paramObject).getAclType());
		}
		// 处理时间段名称
		if (this.model.getTimeRange() != null) {
			this.model.setTimeRangeName(this.model.getTimeRange().getName());
		} else {
			this.model.setTimeRangeName(this.timeRangeName);
		}
		// 处理序号
		try {
			this.model.setAceNum(Integer.parseInt(this.getAceOrder()));
		} catch (Exception ex) {
			this.model.setAceNum(0);
		}
		// 已存在则报错
		if (aceService.existByAce(this.model)) {
			//throw new BusinessException("acl_ace_error_exist");
			addGlobalI18nMessage(Severity.ERROR,"acl_ace_error_exist");
			return false;
		}
		boolean successful = super.doAdd();
		if (successful) {
			this.updateAccessGroupChangeFlag(this.paramObject);
		}
		
		return successful;
		}else{
		return false;
		}
	}

	@Override
	@SuppressWarnings("unchecked")
	@Transactional
	protected boolean doUpdate() {
		// 处理源端口和目的端口
		if (AclUtil.empty(this.model.getSourcePort())) {
			this.model.setSourcePort(this.sourcePort);
		}
		if (AclUtil.empty(this.model.getDesPort())) {
			this.model.setDesPort(this.desPort);
		}
		boolean successful = true;
		boolean beChanged = true;
		if (this.paramObject instanceof Template) {
			AclUtil.filterAce(this.model, ((Template) paramObject).getAccessGroupType());
		} else if (this.paramObject instanceof AccessGroup) {
			AclUtil.filterAce(this.model, ((AccessGroup) paramObject).getAclType());
		}
		// 处理时间段名称
		if (this.model.getTimeRange() != null) {
			this.model.setTimeRangeName(this.model.getTimeRange().getName());
		} else {
			if (this.timeRangeChangedFlag){
				this.model.setTimeRangeName(null);
			}else{
				this.model.setTimeRangeName(this.timeRangeName);
			}
		}
		Ace tempAce = aceService.get(this.model.getId());	
		// 处理序号
		Integer aceNumNew = 0;
		try {
			aceNumNew = Integer.parseInt(this.getAceOrder());
		} catch (Exception ex) {
			aceNumNew = null;
		}
		this.model.setAceNum(aceNumNew);
		// 判断是否进行了修改，未修改则不保存，修改则进行保存操作
		if (tempAce != null && tempAce.equals(this.model)) {
			if (tempAce.equalsStrict(this.model)) {
				return true;
			} else {
				beChanged = (aceNumNew != null && aceNumNew.intValue() != tempAce.getAceNum().intValue());
			}
		} else {
			// 是否存在相同的
			if (aceService.existByAce(this.model)) {
//				throw new BusinessException("acl_ace_error_exist");
				addGlobalI18nMessage(Severity.ERROR,"acl_ace_error_exist");
				return false;
			}
		}
		tempAce = this.model.cloneAce(tempAce);
		this.model = tempAce;		
		this.aceService.update(this.model, aceNumNew);
		successful = true;
		if (successful && beChanged) {
			this.updateAccessGroupChangeFlag(this.paramObject);
		}
		return successful;
	}

	/**
	 * <p>
	 * Description: 删除单个实体操作
	 * </p>
	 * <p>
	 * Create Time: 2009-09-18
	 * </p>
	 * 
	 * @param entity
	 *            要删除的对象
	 */
	@SuppressWarnings("unchecked")
	@Transactional
	public void delete(Ace entity) {
		AccessGroup tempAg = entity.getAccessGroup();
		super.delete(entity);
		this.updateAccessGroupChangeFlag(tempAg);
	}

	/**
	 * 更新ACL组修改标志位
	 * 
	 * @param entity
	 *            ACL组
	 */
	public void updateAccessGroupChangeFlag(EntityObject entity) {
		// 若为ACL组,且该ACL组被设备关联,且changeFlag为false时,将changeFlag改为true
		if (entity != null && entity instanceof AccessGroup) {
			AccessGroup tempAg = (AccessGroup) entity;
			tempAg = accessGroupService.get(tempAg.getId());
			if (tempAg != null){
				if (deviceAccessGroupService.existByAccessGroup(tempAg)) {
					accessGroupService.refresh(tempAg);
					if (!tempAg.getIsChanged()) {
						tempAg.setIsChanged(true);
						accessGroupService.update(tempAg);
					}
					deviceAccessGroupService.updateChangedByAccessGroup(tempAg);
				}
				accessGroupAction.setModel(tempAg);
				deviceManageInAccessGroupAction.setAclDeviceEntityModelList(null);
				//deviceManageInAccessGroupAction.getAclDeviceEntityModelList(tempAg);
			}
		}
	}

	public Integer getAceCount() {
		return aceCount;
	}

	public void setAceCount(Integer aceCount) {
		this.aceCount = aceCount;
	}

	public String toUpdatePage(EntityObject editModel, String previousPage) {
		this.sourcePort = null;
		this.desPort = null;
		this.timeRangeName = null;
		this.aceOrder = null;
		if (editModel != null) {
			Ace tempModel = (Ace) editModel;
			this.timeRangeName = tempModel.getTimeRangeName();
			this.sourcePort = this.getPortString(tempModel.getSourcePort());
			this.desPort = this.getPortString(tempModel.getDesPort());
			this.aceOrder = tempModel.getAceNum().toString();
			if (tempModel.getTimeRange() == null && !AclUtil.empty(tempModel.getTimeRangeName())){
				this.timeRangeChangedFlag = false;
			}
		}
		return super.toUpdatePage(editModel, previousPage);
	}

	public void changeTimeRangeName() {
		if (this.model != null) {
			this.timeRangeChangedFlag = true;
			if (this.model.getTimeRange() != null) {
				this.timeRangeName = this.model.getTimeRange().getName();
			} else {
				this.timeRangeName = "";
			}
		}
	}

	public List<SelectItem> getPoryTypeItems() {
		List<SelectItem> resultList = new ArrayList<SelectItem>();
		if (this.model != null && !AclUtil.empty(this.model.getProtocolType()) 
				&& (ProtocolTypeEnum.tcp.toString().equals(this.model.getProtocolType()) 
						|| ProtocolTypeEnum.udp.toString().equals(this.model.getProtocolType()))){
			List<PortTypeEnum> portTypeEnumList = PortTypeEnum.getEnumList(this.model.getProtocolType());
			for (PortTypeEnum protTypeEnum : portTypeEnumList) {
				resultList.add(new SelectItem(protTypeEnum.value()));
			}
		}
		return resultList;
	}
	
	public void resetPort(){
		if (this.model != null){
			this.model.setSourcePort(null);
			this.model.setDesPort(null);
		}
		this.sourcePort = null;
		this.desPort = null;
	}

	public String getPortString(String port) {
		if (AclUtil.empty(port)) {
			return "";
		}
		port = port.trim();
		try {
			Integer.parseInt(port);
			return port;
		} catch (Exception ex) {
			String portValue = PortTypeEnum.getEnumValue(port);
			if (portValue == null){
				portValue = port;
			}
			return portValue;
		}
	}

	public void changeSourcePort() {
		if (!AclUtil.empty(this.model.getSourcePort())) {
			this.sourcePort = PortTypeEnum.getEnumValue(this.model.getSourcePort());
		} else {
			this.sourcePort = "";
		}
	}

	public void changeDesPort() {
		if (!AclUtil.empty(this.model.getDesPort())) {
			this.desPort = PortTypeEnum.getEnumValue(this.model.getDesPort());
		} else {
			this.desPort = "";
		}
	}
	
	//-------------modify by sinyee 2010-10-22 being----------------

	
	@AddSuccessInfo
	public String addEntity(){
		this.add();
		return null;
	}
	
	@AddSuccessInfo
	public String updateEntity(){
		this.update();
		return null;
	}
	
	//--------------modify by sinyee 2010-10-22 end----------------
	

}
